﻿using Nemerle;
using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;
using Nemerle2.Compiler;
using Microsoft.Cci;
using Nemerle.Assertions;

namespace MetadataReader.CCI
{
  /// <summary>
  /// Description of CciTypeParameterInfo.
  /// </summary>
  internal class CciTypeParameterInfo : ITypeParameterInfo
  {
    _typeParam : IGenericTypeParameter;
    _provider  : CciMetadataProvider;

    public this([NotNull] provider : CciMetadataProvider, [NotNull] typeParam : IGenericTypeParameter)
    {
      _typeParam = typeParam;
      _provider  = provider;
    }

    #region ITypeParameterInfo  Members
    
    public Constraints : list[FixedType]
    {
      [Memoize] get { _typeParam.Constraints.Map(ty => _provider.GetType(ty)) }
    }
    
    public HasDefaultConstructor : bool { [Memoize] get { _typeParam.MustHaveDefaultConstructor } }
    
    public IsContravariant : bool
    {
      [Memoize] get { _typeParam.Variance == TypeParameterVariance.Contravariant }
    }
    
    public IsCovariant : bool
    {
      [Memoize] get { _typeParam.Variance == TypeParameterVariance.Covariant }
    }
    
    public IsValueType     : bool   { [Memoize] get { _typeParam.IsValueType } }
    public IsReferenceType : bool   { [Memoize] get { _typeParam.IsReferenceType } }
    
    public Name            : string { [Memoize] get { _typeParam.Name.Value } }

    public LowerBound : FixedType
    {
      [Memoize]
      get
      {
        match (Constraints)
        {
          | [] when IsValueType => _provider.StandardTypes.ValueType
          | []                  => _provider.StandardTypes.Object
          | [x]                 => x
          | lst                 => FixedType.Intersection(lst)
        }
      }
    }

    #endregion
    
  }
}
